﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WevPanel
{
    public partial class FormOllioscope : Form
    {
        private WaveGrapher grapher;
        private List<string> graph_names;
        public FormOllioscope()
        {
            InitializeComponent();
        }

        private void FormOllioscope_FormClosing(object sender, FormClosingEventArgs e)
        {
            Hide();
            e.Cancel = true;
        }

        public void UpdateTree(TreeNode value)
        {
            WevSlaveTree.Nodes.Clear();
            WevSlaveTree.Nodes.Add(value);
        }

        private void WevSlaveTree_DoubleClick(object sender, EventArgs e)
        {
            if (checkedNodes.Items.Count >= 4)
            {
                MessageBox.Show("At Most 4 Curves Can be Added.");
                return;
            }
            if (WevSlaveTree.SelectedNode.Nodes.Count == 0)
            {
                string name = WevSlaveTree.SelectedNode.Text;
                string full_name = GetFullNameFromTreeNode(WevSlaveTree.SelectedNode);
                if(!checkedNodes.Items.Contains(full_name))
                {
                    checkedNodes.Items.Add(full_name, isChecked:true);
                }
            }
        }

        /// <summary>
        /// 从TreeNode提取变量名称全称
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public string GetFullNameFromTreeNode(TreeNode node)
        {
            TreeNode n = node;
            var name_list = new List<string>();
            if(n is null)
            {
                throw new Exception("null tree node.");
            }
            while(true)
            {
                name_list.Add(n.Text);
                if (n.Parent is null)
                    break;
                n = n.Parent;
            }
            string full_name = "";
            for (int i = name_list.Count; i > 0; i--)
            {
                full_name += (name_list[i - 1] + (i != 1 ? "." : ""));
            }
            return full_name;
        }

        /// <summary>
        /// 从对象的完成名称获取值
        /// </summary>
        /// <param name="value">对象实例</param>
        /// <param name="name">属性名称比如A.B.C获取</param>
        /// <returns></returns>
        public object GetValueFromFullName(object value ,string name)
        {
            object tmp = value;
            string[] name_list = name.Split('.');
            for (int i = 0; i < name_list.Length; i++)
            {
                tmp = GetValueFromName(tmp, name_list[i]);
            }
            return tmp;
        }

        /// <summary>
        /// 从对象的属性名获取值
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="value">对象实例</param>
        /// <param name="name">属性名称</param>
        /// <returns></returns>
        public object GetValueFromName<T>(T value, string name)
        {
            return value.GetType().GetProperty(name).GetValue(value);
        }

        private void tmPlay_Tick(object sender, EventArgs e)
        {
            double[] points = new double[grapher.channel_length];
            for(int i=0;i<points.Length;i++)
            {
                object value =  GetValueFromFullName(FormMain.SerialDriver_.Slave, graph_names[i]);
                points[i] = Convert.ToDouble(value);
            }
            grapher.AddPoints(points);
            grapher.RefreshCurve();
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            if(checkedNodes.Items.Count == 0)
                return;

            if (tmPlay.Enabled)
                return;

            graph_names.Clear();
            grapher.channel_length = checkedNodes.Items.Count;
            for(int i=0;i<grapher.channel_length;i++)
            {
                graph_names.Add(checkedNodes.Items[i].ToString());
            }
            grapher.InitAxis(graph_names.ToArray());
            tmPlay.Start();
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            checkedNodes.Items.Clear();
        }

        private void FormOllioscope_Load(object sender, EventArgs e)
        {
            grapher = new WaveGrapher(ref Zed);
            graph_names = new List<string>();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            tmPlay.Stop();
        }
    }
}
